package com.example.mail.config;

import com.sun.mail.util.MailSSLSocketFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import java.util.Properties;

/**
 * 自定义邮件推送组件
 */
@Component
public class MailPushService {

    private final Logger LOGGER = LoggerFactory.getLogger(MailPushService.class);


    @Value("${mail.host}")
    private String host;

    @Value("${mail.port}")
    private String port;

    @Value("${mail.protocol}")
    private String protocol;

    @Value("${mail.username}")
    private String username;

    @Value("${mail.password}")
    private String password;

    @Value("${mail.fromEmail}")
    private String fromEmail;

    @Value("${mail.fromPersonal}")
    private String fromPersonal;

    @Autowired
    private JavaMailSender mailSender;


    /**
     * 发送邮件（简单模式）
     * @param toEmail
     * @param subject
     * @param content
     */
    public void sendMail(String toEmail, String subject,String content)  {
        try {
            final Properties props = new Properties();
            //服务器
            props.put("mail.smtp.host", host);
            //端口
            props.put("mail.smtp.port", port);
            //协议
            props.setProperty("mail.transport.protocol", protocol);
            //用户名
            props.put("mail.user", username);
            //密码
            props.put("mail.password", password);
            //使用smtp身份验证
            props.put("mail.smtp.auth", "true");

            //开启安全协议
            MailSSLSocketFactory sf = new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);
            props.put("mail.smtp.ssl.enable", "true");
            props.put("mail.smtp.ssl.socketFactory", sf);
            Authenticator authenticator = new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(props.getProperty("mail.user"),
                            props.getProperty("mail.password"));
                }
            };

            Session session = Session.getDefaultInstance(props, authenticator);
            session.setDebug(true);
            MimeMessage mimeMessage = new MimeMessage(session);
            mimeMessage.setFrom(new InternetAddress(fromEmail, MimeUtility.encodeText(fromPersonal)));
            mimeMessage.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(toEmail));
            mimeMessage.setSubject(subject);
            mimeMessage.setContent(content, "text/html;charset=UTF-8");

            //保存信息
            mimeMessage.saveChanges();
            //发送消息
            Transport.send(mimeMessage);
            LOGGER.info("简单邮件已经发送。");
        } catch (Exception e) {
            LOGGER.error("发送简单邮件时发生异常！", e);
        }
    }


    /**
     * 发送邮件（复杂模式）
     * @param toEmail    接受者邮箱
     * @param subject    主题
     * @param sendHtml   内容
     * @param attachment 附件
     */
    public void sendMail(String toEmail, String subject, String sendHtml, File attachment) {
        try {
            //设置了附件名过长问题
            System.setProperty("mail.mime.splitlongparameters", "false");
            final Properties props = new Properties();
            //服务器
            props.put("mail.smtp.host", host);
            //端口
            props.put("mail.smtp.port", port);
            //协议
            props.setProperty("mail.transport.protocol", protocol);
            //用户名
            props.put("mail.user", username);
            //密码
            props.put("mail.password", password);
            //使用smtp身份验证
            props.put("mail.smtp.auth", "true");

            //开启安全协议
            MailSSLSocketFactory sf = new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);
            props.put("mail.smtp.ssl.enable", "true");
            props.put("mail.smtp.ssl.socketFactory", sf);
            Authenticator authenticator = new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(props.getProperty("mail.user"),
                            props.getProperty("mail.password"));
                }
            };

            Session session = Session.getDefaultInstance(props, authenticator);
            session.setDebug(true);
            MimeMessage mimeMessage = new MimeMessage(session);
            // 发送者邮箱
            mimeMessage.setFrom(new InternetAddress(fromEmail, MimeUtility.encodeText(fromPersonal)));
            // 接受者邮箱
            mimeMessage.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(toEmail));
            // 邮件主题
            mimeMessage.setSubject(subject);
            // 定义邮件内容
            Multipart multipart = new MimeMultipart();

            // 添加邮件正文
            BodyPart contentPart = new MimeBodyPart();
            contentPart.setContent(sendHtml, "text/html;charset=UTF-8");
            multipart.addBodyPart(contentPart);

            // 添加附件
            if (attachment != null) {
                BodyPart attachmentBodyPart = new MimeBodyPart();
                // MimeUtility.encodeWord可以避免文件名乱码
                FileDataSource fds=new FileDataSource(attachment);
                attachmentBodyPart.setDataHandler(new DataHandler(fds));
                attachmentBodyPart.setFileName(MimeUtility.encodeText(fds.getName()));
                multipart.addBodyPart(attachmentBodyPart);
            }

            // 将multipart对象放到message中
            mimeMessage.setContent(multipart);

            //保存信息
            mimeMessage.saveChanges();
            //发送消息
            Transport.send(mimeMessage);
            LOGGER.info("邮件已经发送。");
        } catch (Exception e) {
            LOGGER.error("发送邮件时发生异常！", e);
        }
    }
}
